package com.meritdata.cloud.data.manager.model.service.impl;


import com.meritdata.cloud.data.manager.model.entity.*;
import com.meritdata.cloud.data.manager.model.repository.DataModelColumnRepository;
import com.meritdata.cloud.data.manager.model.repository.DataQualityRuleColumnConfigRepository;
import com.meritdata.cloud.data.manager.model.repository.TdColumnConfigRepository;
import com.meritdata.cloud.data.manager.model.service.IDataModelColumnService;
import com.meritdata.cloud.data.standard.desensitization.entity.QTdDatamaskRule;
import com.meritdata.cloud.data.standard.quality.entity.QTdDataQualityRule;
import com.meritdata.cloud.data.standard.quality.entity.TdDataQualityRule;
import com.querydsl.jpa.impl.JPAQueryFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

@Service
@Transactional
public class DataModelColumnService implements IDataModelColumnService {
    @Autowired
    private JPAQueryFactory jpaQueryFactory;

    @Autowired
    private DataQualityRuleColumnConfigRepository dataQualityRuleColumnConfigRepository;

    @Autowired
    private TdColumnConfigRepository tdColumnConfigRepository;

    @Autowired
    private DataModelColumnRepository dataModelColumnRepository;

    @SuppressWarnings("unchecked")
    @Override
    public List<Map> getColumnInfoData(Long modelId) {
        QTdMetadataColumn qTdMetadataColumn = QTdMetadataColumn.tdMetadataColumn;
        QTdColumnConfig qTdColumnConfig = QTdColumnConfig.tdColumnConfig;
        QTdDatamaskRule qTdDatamaskRule = QTdDatamaskRule.tdDatamaskRule;
        QTdDataQualityRuleColumnConfig qTdDataQualityRuleColumnConfig = QTdDataQualityRuleColumnConfig.tdDataQualityRuleColumnConfig;
        QTdDataQualityRule qTdDataQualityRule = QTdDataQualityRule.tdDataQualityRule;
        Long count = jpaQueryFactory.selectFrom(qTdMetadataColumn).where(qTdMetadataColumn.name.like("column%")).fetchCount();
        if (count == 0) {
            for(int i=1;i<=4;i++){
                TdMetadataColumn tdDataModelColumn = new TdMetadataColumn();
                tdDataModelColumn.setId(i);
                tdDataModelColumn.setName("column"+i);
                tdDataModelColumn.setType("string");
                tdDataModelColumn.setIsIndex(0);
                tdDataModelColumn.setIsForeignKey(0);
                tdDataModelColumn.setNullable(0);
                tdDataModelColumn.setIsPrimaryKey(0);
                tdDataModelColumn.setTableId(111111L);
                dataModelColumnRepository.save(tdDataModelColumn);
                TdColumnConfig tdColumnConfig = new TdColumnConfig();
                tdColumnConfig.setTitle("字段"+i);
                tdColumnConfig.setId((long) i);
                tdColumnConfig.setTableId(111111L);
                tdColumnConfig.setCode("column"+i);
                tdColumnConfigRepository.save(tdColumnConfig);
            }
        }
        List<Map> result = jpaQueryFactory.select(
                qTdMetadataColumn.id,
                qTdColumnConfig.id,
                qTdMetadataColumn.name,
                qTdMetadataColumn.type,
                qTdColumnConfig.title,
                qTdMetadataColumn.isPrimaryKey,
                qTdMetadataColumn.isForeignKey,
                qTdMetadataColumn.isIndex,
                qTdMetadataColumn.nullable,
                qTdColumnConfig.securityLevelCode,
                qTdColumnConfig.datamaskId,
                qTdDatamaskRule.name
                ).from(qTdMetadataColumn).
                leftJoin(qTdColumnConfig).on(qTdMetadataColumn.tableId.eq(qTdColumnConfig.tableId).and(qTdColumnConfig.code.eq(qTdMetadataColumn.name))).
                leftJoin(qTdDatamaskRule).on(qTdColumnConfig.datamaskId.eq(qTdDatamaskRule.id)).
                where(qTdMetadataColumn.tableId.eq(modelId)).fetch()
                .stream().map(item -> {
                    Map map = new HashMap<String,Object>();
                    map.put("id", item.get(qTdMetadataColumn.id));
                    map.put("columnConfigId", item.get(qTdColumnConfig.id));
                    map.put("name", item.get(qTdMetadataColumn.name));
                    map.put("type", item.get(qTdMetadataColumn.type));
                    map.put("title", item.get(qTdColumnConfig.title));
                    map.put("isPrimaryKey", item.get(qTdMetadataColumn.isPrimaryKey));
                    map.put("isForeignKey", item.get(qTdMetadataColumn.isForeignKey));
                    map.put("isIndex", item.get(qTdMetadataColumn.isIndex));
                    map.put("nullable", item.get(qTdMetadataColumn.nullable));
                    map.put("securityLevelCode", item.get(qTdColumnConfig.securityLevelCode));
                    map.put("datamaskId", item.get(qTdColumnConfig.datamaskId));
                    map.put("datamaskName", item.get( qTdDatamaskRule.name));
                    return map;
                }).collect(Collectors.toList());
        for (Map<String, Object> tdMetadataColumn :
                result) {
            tdMetadataColumn.put("qualityRuleList",jpaQueryFactory.select(qTdDataQualityRuleColumnConfig.id, qTdDataQualityRule.name
            ).from(qTdDataQualityRuleColumnConfig)
                    .leftJoin(qTdMetadataColumn)
                    .on(qTdDataQualityRuleColumnConfig.columnId.eq(qTdMetadataColumn.id))
                    .leftJoin(qTdDataQualityRule).
                            on(qTdDataQualityRuleColumnConfig.qualityRuleId.eq(qTdDataQualityRule.id))
                    .where(qTdMetadataColumn.id.eq((Long) tdMetadataColumn.get("id"))).fetch()
                    .stream().map(item -> {
                        Map map = new HashMap();
                        map.put("qualityRuleColumnConfigId", item.get(qTdDataQualityRuleColumnConfig.id));
                        map.put("qualityRuleName", item.get(qTdDataQualityRule.name));
                        return map;
                    }).collect(Collectors.toList()));
        }
        return result;
    }
    @Override
    public List<TdDataQualityRule> qualityRuleList() {
        QTdDataQualityRule qTdDataQualityRule = QTdDataQualityRule.tdDataQualityRule;
        return jpaQueryFactory.selectFrom(qTdDataQualityRule).fetch();
    }
    @Override
    public boolean saveQualityRule(long tableId, long columnId, String columnName, long qualityRuleId, long dictPartId, long dictPartColumnId) {
        if (qualityRuleId != 0) {
            QTdDataQualityRuleColumnConfig tdDataQualityRuleColumnConfig = QTdDataQualityRuleColumnConfig.tdDataQualityRuleColumnConfig;
            Long count = jpaQueryFactory.selectFrom(tdDataQualityRuleColumnConfig).where(tdDataQualityRuleColumnConfig.columnId.eq(columnId).
                    and(tdDataQualityRuleColumnConfig.qualityRuleId.eq(qualityRuleId))).fetchCount();
            if (count > 0) {
                return false;
            }
            TdDataQualityRuleColumnConfig qualityRule = new TdDataQualityRuleColumnConfig();
            qualityRule.setColumnId(columnId);
            qualityRule.setQualityRuleId(qualityRuleId);
            qualityRule.setCreateTime(new Date());
            qualityRule.setCreator((long) 1);
            dataQualityRuleColumnConfigRepository.save(qualityRule);
        } else {
            tdColumnConfigRepository.updateColumnConfig(tableId, columnName, dictPartId, dictPartColumnId);
        }
        return true;
    }

    @Override
    public boolean delQualityRule(long qualityRuleColumnConfigId) {
        dataQualityRuleColumnConfigRepository.deleteById(qualityRuleColumnConfigId);
        return true;
    }

    @Override
    public boolean saveMaskRule(long tableId, String columnName, long datamaskId, int securityLevelCode) {
        tdColumnConfigRepository.updateColumnMaskRule(tableId,columnName,datamaskId,securityLevelCode);
        return true;
    }

    @Override
    public boolean delMaskRule(long columnConfigId) {
        tdColumnConfigRepository.delMaskRule(columnConfigId);
        return true;
    }

    @Override
    public boolean multiSaveQualityRule(long tableId, long[] columnIds, String[] columnNames, long qualityRuleId, long dictPartId, long dictPartColumnId) {
        boolean flag = true;
        for (int i=0;i<columnIds.length;i++){
           flag = saveQualityRule(tableId,columnIds[i],columnNames[i],qualityRuleId,dictPartId,dictPartColumnId);
          if(!flag){
             break;
          }
        }
        return flag;
    }

    @Override
    public boolean multiSaveMaskRule(long tableId, String[] columnNames, long datamaskId, int securityLevelCode) {
        for (int i=0;i<columnNames.length;i++){
            saveMaskRule(tableId,columnNames[i],datamaskId,securityLevelCode);
        }
        return true;
    }
}
